#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/sendfile.h>

#define SERVER_ADDR "127.0.0.1" // 定义服务器的IP地址
#define SERVER_PORT 8080		// 定义连接的端口号，FTP标准端口
#define BUFSIZE 1024			// 定义缓冲区大小

void* send_text_thread(void* arg);
void* recv_text_thread(void* arg);
int recv_file(int socket_desc,char filename[]);
int send_file(int socket_desc, char* file_name);

int main()
{
	int client_socket;				// 客户端的socket描述符
	struct sockaddr_in server_addr; // 服务器的地址信息

	// 创建客户端socket
	client_socket = socket(AF_INET, SOCK_STREAM, 0);
	if (client_socket < 0)
	{
		perror("Socket creation failed");
		exit(EXIT_FAILURE);
	}

	// 设置服务器地址结构
	memset(&server_addr, 0, sizeof(server_addr));
	server_addr.sin_family = AF_INET;					  // 使用IPv4地址
	server_addr.sin_addr.s_addr = inet_addr(SERVER_ADDR); // 服务器的IP地址
	server_addr.sin_port = htons(SERVER_PORT);			  // 服务器的端口号

	// 连接到服务器
	if (connect(client_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
	{
		perror("Connect failed");
		exit(EXIT_FAILURE);
	}

    // 发送文件
    send_file(client_socket,"example.txt");

	pthread_t send_thread, recv_thread;
    
    // 创建并启动发送线程
    if (pthread_create(&send_thread, NULL, send_text_thread, (void*)&client_socket))
    {
        perror("Error creating send thread");
        exit(EXIT_FAILURE);
    }

    // 创建并启动接收线程
    if (pthread_create(&recv_thread, NULL, recv_text_thread, (void*)&client_socket))
    {
        perror("Error creating recv thread");
        exit(EXIT_FAILURE);
    }

    // 等待两个线程完成
    pthread_join(send_thread, NULL);
    pthread_join(recv_thread, NULL);

	// 关闭socket连接
	close(client_socket);
	
	return 0;
}


void* send_text_thread(void* arg)
{
    int* client_socket = (int*)arg;
    while(1) // 检查关闭信号
    {
        char buff[BUFSIZE];
        printf("请输入消息：");
        scanf("%s",buff);

        ssize_t sent_bytes = send(*client_socket, buff, BUFSIZE, 0);
        if (sent_bytes == -1) {
            perror("发送失败");
        } else if (sent_bytes < BUFSIZE) {
            printf("警告：未能发送所有数据。已发送 %zd 字节，共 %d 字节。\n", sent_bytes, BUFSIZE);
        } else {
            printf("消息已成功发送。\n");
        }
    }
}

void* recv_text_thread(void* arg)
{
    int* client_socket = (int*)arg;
    while(1)  // 检查关闭信号
    {
        char buff[BUFSIZE];
        ssize_t recv_bytes = recv(*client_socket, buff, BUFSIZE, 0);
        if (recv_bytes == -1) {
            perror("接收失败");
        } else if (recv_bytes == 0) {
            printf("连接已关闭。\n");
            break;
        } else {
            printf("收到消息：%s\n", buff);
        }
		if (strcmp(buff, "exit") == 0)
		{
			break;
		}
    }
	
}


int recv_file(int socket_desc,char filename[])
{
    int file_size;
    char *data;
    // 接收客户端发送的文件大小
    recv(socket_desc, &file_size, sizeof(int), 0);
    // 根据文件大小动态分配内存
    data = malloc(file_size + 1);
    // 创建一个新文件
    FILE *fp = fopen(filename,"W");
    
    // 接收文件数据
    int r = recv(socket_desc, data, file_size, 0);
    fwrite(data,1,file_size,fp);
    fclose(fp);

    return 1;
}


int send_file(int socket_desc, char* file_name)
{
	struct stat	obj;
	int file_desc, file_size;
	stat(file_name, &obj);
	file_desc = open(file_name, O_RDONLY);
	file_size = obj.st_size;

	send(socket_desc, &file_size, sizeof(int), 0);

	sendfile(socket_desc, file_desc, NULL, file_size);
	printf("文件：%s发送成功\n",file_name);        

	return 1;
}